#import "RNCancelButtonCell.h"

static NSColor *normalFillColor, *hoverFillColor, *pressedFillColor;

@implementation RNCancelButtonCell

@synthesize mouseIsHovering = mouseIsHovering_;
@synthesize trackingMouse = trackingMouse_;
@synthesize trackingRect = trackingRect_;


#pragma mark -
#pragma mark Class methods

+(void)initialize {
    normalFillColor = [NSColor colorWithCalibratedWhite:0.72 alpha:1.0f];
    hoverFillColor = [NSColor colorWithCalibratedWhite:0.67 alpha:1.0f];
    pressedFillColor = [NSColor colorWithCalibratedWhite:0.55 alpha:1.0f];
}

+ (BOOL)prefersTrackingUntilMouseUp {
    return YES;
}


#pragma mark -
#pragma mark Initialization

-(id)initTextCell:(NSString *)title {
    if (!(self = [super initTextCell:title]))
        return nil;
    [self sendActionOn:0];
    return self;
}

-(id)initWithCoder:(NSCoder *)coder {
    if (!(self = [super initWithCoder:coder]))
        return nil;
    [self sendActionOn:0];
    return self;
}

- (id)copyWithZone:(NSZone *)zone {
    RNCancelButtonCell *copy = [super copyWithZone:zone];
    if (!copy)
        return nil;
    [copy setMouseIsHovering:[self mouseIsHovering]];
    [copy setTrackingRect:[self trackingRect]];
    return copy;
}


#pragma mark -
#pragma mark Drawing

-(void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
    NSBezierPath *buttonPath = [NSBezierPath bezierPathWithOvalInRect:cellFrame];
    NSColor *fillColor = [self mouseIsHovering] ? hoverFillColor : normalFillColor;
    if ([self trackingMouse] && [self mouseIsHovering])
        fillColor = pressedFillColor;
    [fillColor setFill];
    [buttonPath fill];

    [[NSColor whiteColor] setStroke];
    NSBezierPath *linePath = [NSBezierPath bezierPath];
    CGFloat big = NSHeight(cellFrame) * 0.69375;
    CGFloat small = NSWidth(cellFrame) * 0.30625;
    NSPoint point = cellFrame.origin;
    point.x += small;
    point.y += big;
    [linePath moveToPoint:point];
    point = cellFrame.origin;
    point.x += big;
    point.y += small;
    [linePath lineToPoint:point];
    [linePath stroke];
    
    linePath = [NSBezierPath bezierPath];
    point = cellFrame.origin;
    point.x += small;
    point.y += small;
    [linePath moveToPoint:point];
    point = cellFrame.origin;
    point.x += big;
    point.y += big;
    [linePath lineToPoint:point];
    [linePath stroke];
}


#pragma mark -
#pragma mark Event handling

- (void)mouseEntered:(NSEvent *)event {
    [self setMouseIsHovering:YES];
}

- (void)mouseExited:(NSEvent *)event {
    [self setMouseIsHovering:NO];
}

- (BOOL)trackMouse:(NSEvent *)theEvent inRect:(NSRect)cellFrame ofView:(NSView *)controlView untilMouseUp:(BOOL)untilMouseUp {
    [self setTrackingRect:cellFrame];
    return [super trackMouse:theEvent inRect:cellFrame ofView:controlView untilMouseUp:untilMouseUp];
}

- (BOOL)startTrackingAt:(NSPoint)startPoint inView:(NSView *)controlView {
    [self setTrackingMouse:YES];
    [self setMouseIsHovering:YES];
    [controlView setNeedsDisplayInRect:[self trackingRect]];
    return YES;
}

- (BOOL)continueTracking:(NSPoint)lastPoint at:(NSPoint)currentPoint inView:(NSView *)controlView {
    NSEvent *event = nil;
    do {
        event = [NSApp nextEventMatchingMask:(NSMouseEnteredMask | NSMouseExitedMask) untilDate:nil inMode:NSEventTrackingRunLoopMode dequeue:YES];
        if (event)
            [NSApp sendEvent:event];
    }
    while (event);
    [self setMouseIsHovering:[controlView mouse:currentPoint inRect:[self trackingRect]]];
    [controlView setNeedsDisplayInRect:[self trackingRect]];
    return YES;
}

- (void)stopTracking:(NSPoint)lastPoint at:(NSPoint)stopPoint inView:(NSView *)controlView mouseIsUp:(BOOL)flag {
    if ([controlView mouse:stopPoint inRect:[self trackingRect]]) 
        [NSApp sendAction:[self action] to:[self target] from:self];
    [self setTrackingRect:NSZeroRect];
    [self setTrackingMouse:NO];
    [controlView setNeedsDisplayInRect:[self trackingRect]];
}
@end
